#version 330 core 
out vec4 FragColor;
in vec2 TexCoord;
in vec3 FragPos;
in vec3 Normal;

uniform sampler2D TextureId;



struct DirLight {
    vec3 direction;
    vec3 ambient;
    vec3 diffuse;
    vec3 specular;
};
uniform DirLight dirlight;



vec3 CalcDirLight(DirLight light, vec3 normal)
{
    vec3 lightDir = normalize(-light.direction);
    // lightDir = vec3(0,1,1);

    // 漫反射着色
    float diff = max(dot(normal, lightDir), 0.0);
   
    // 合并结果
    vec3 ambient  = light.ambient  * vec3(texture(TextureId, TexCoord));
    vec3 diffuse  = light.diffuse  * diff * vec3(texture(TextureId, TexCoord));
    
  
    return (ambient + diffuse);
}


struct PointLight {
    vec3 position;

    float constant;
    float linear;
    float quadratic;

    vec3 ambient;
    vec3 diffuse;
    vec3 specular;
};  

#define NR_POINT_LIGHTS 64
uniform PointLight pointLights[NR_POINT_LIGHTS];
uniform int PointLightSize;

vec3 CalcPointLight(PointLight light, vec3 normal, vec3 fragPos)
{
    vec3 lightDir = normalize(light.position - fragPos);
    // 漫反射着色
    float diff = max(dot(normal, lightDir), 0.0);
  
    // 衰减
    float distance    = length(light.position - fragPos);
    float attenuation = 1.0 / (light.constant + light.linear * distance + 
                 light.quadratic * (distance * distance));    
    // 合并结果
    vec3 ambient  = light.ambient  * vec3(texture(TextureId, TexCoord));
    vec3 diffuse  = light.diffuse  * diff * vec3(texture(TextureId, TexCoord));
    ambient  *= attenuation;
    diffuse  *= attenuation;
    return (ambient + diffuse );
}

void main()
{
// properties
    vec3 norm = normalize(Normal);
 
    
    // == =====================================================
    // Our lighting is set up in 3 phases: directional, point lights and an optional flashlight
    // For each phase, a calculate function is defined that calculates the corresponding color
    // per lamp. In the main() function we take all the calculated colors and sum them up for
    // this fragment's final color.
    // == =====================================================
    // phase 1: directional lighting
    vec3 result = CalcDirLight(dirlight, norm);
    // phase 2: point lights
    for(int i = 0; i < PointLightSize; i++)
        result += CalcPointLight(pointLights[i], norm, FragPos);    

    
    FragColor = vec4(result, 1.0);
    // FragColor = texture2D(TextureId, TexCoord);

}